lpunbfandomcom-20200214-history
Ruby - 1/2013
Ruby é uma linguagem de alto nível orientada à objeto. Ela tem evoluído significativamente, sendo cada vez mais usada. Ela se tornou muito popular devido a sua alta legibilidade e baixo custo, além de boa confiabilidade e capacidade de escrita. A existência de vários frameworks e tutoriais, além de uma vasta documentação torna Ruby uma linguagem muito atrativa. 'Contexto' Ruby é uma linguagem de script orientada a objetos escrita em linguagem C. Surgiu no Japão em 1995 criada por Yukihiro Matsumoto conhecido também como Matz que criou Ruby pelo simples fato de querer uma linguagem de script fosse mais poderosa que Perl e mais orientada a objetos que Python. 'Diretrizes' 'Premissas' Ruby foi criado para ser "uma linguagem de script" mais poderosa do que Perl e mais orientada à objeto do que Python", como afirma o criador da linguagem. Além disso, também foi originada para balancear programação funcional e impertiva. O projeto era de uma ferramenta de entendimento simples, mas de profundidade extensa. 'Usuários característicos' Por ser uma linguagem interpretada direcionada a scripting e que devido a sua simplicidade e flexibilidade possibilita uma produtividade elevada, ela é largamente utilizada por programadores Web. 'Domínio de aplicação' Ruby é implementável a uma faixa bastante extensa de aplicações, bem como boa parte das linguagens orientadas a objetos. Seu uso mais popular é no desenvolvimento de aplicações web como o Ruby on Rails, voltado à orientação a bancos de dados, mas Ruby pode ser usada em muitos grandes campos, desde que não exijam processamento imediato de informações. Aplicações de desktop, scripting e até mesmo computação científica podem tomar Ruby como base. Temos como exemplo também as aplicações: Rails, Postgresql, Rghost, Brazilian_rails. 'Características' 'Custo' Análise Quanto maior a complexidade e quanto mais recursos contém a linguagem, maior o grau de dificuldade de aprendizado. Ruby é uma linguagem de fácil aprendizado, diminuindo o tempo necessário para treinamento. Essa característica está ligada a sua sintaxe baseada em outras linguagens. Escrita de Programas/Sistemas de Implementação está ligado aos fatores de simplicidade e expressividade que o Ruby oferece. A linguagem provê ferramentas que facilitam esta tarefa como: JRuby que é um implementação Ruby em cima de uma Máquina Virtual Java, que permite a incorporação do interpretador em qualquer aplicação Java com pleno acesso bidirecional entre o Java e o código Ruby; também o Ruby On Rails que é o framework para desenvolvimento web escrito em linguagem Ruby. Compilação de Programas/Execução de Programas: O Ruby é uma linguagem interpretada e é tipado dinamicamente (o ambiente runtime faz o trabalho em tempo de execução). Existem várias formas de se escrever um programa que executa a mesma tarefa, porém quanto mais complexa for a tarefa, maior será a exigência e isso em Ruby seria como entregar um maior volume de trabalho ao o runtime. Manutenção do Programas/ Confiabilidade em Sistemas Críticos mede-se principalmente pelas suas características de legibilidade. Utilizando Ruby teremos um código mais legível e de mais fácil manutenção, facilitado pelo uso intensivo de orientação a objetos. Uma tecnologia que facilita a manutenção são os frameworks (RubyOnRails) e a organização da implementação em componentes. Que permitem um baixo acoplamento, encapsula o que há de comum em frameworks e as particularidades e possibilita a criação e inserção de novos componentes de acordo com a demanda. 'Confiabilidade' Análise A tipagem em Ruby é caracterizada como forte e dinâmica. Uma linguagem ser dinamicamente tipada quer dizer que o tipo de uma variável pode mudar em runtime. Uma linguagem fortemente tipada causa exceção caso vários tipos sejam misturados em uma expressão. Esta característica elimina o problema de mistura de tipos. No entanto, por sua dinamicidade, não definimos categoricamente como a variável deveria se comportar, podendo ocorrer comportamentos inesperados em tempo de execução. A linguagem tem suporte a exceções, possibilitando o tratamento de erros previstos pelo programador. Porém, ela possui suporte a aliasing, possibilitando vários nomes referenciando variáveis/objetos identicos, causando sinonímia. Com o uso de exceções, o programa se torna seguro para problemas previstos, mas o uso de alias é prejudicial para sua confiablidade. Com estes pontos, podemos dizer que Ruby é uma linguagem segura. Apesar de ter características que possibilitam a insegurança da aplicação, ferramentas para a tratamento de erros são presentes. Em suma, Ruby não deve ser usado em sistemas de alto risco, mas pode ser usado para várias aplicações de baixo e médio risco. Comparação Podemos comparar a comfiabilidade de Ruby com a de outras linguagens de outros paradigmas: Hugs98 é dinamicamente e fortemente tipada. Além disto, ela possui análise preguiçosa (permite uso de “propriedades infinitas”) e possibilita o uso de declaração estática de variáveis. No entanto, não tem suporte para exceções, aliasing e verificação estática de tipo. Prolog é dinamicamente e fracamente tipada. A linguagem possibilita o uso de alias, mas não trata exceções ou verifica estaticamente tipos de variáveis. Java é estaticamente e fortemente tipada. Adicionalmente, declaração dinâmica é possível, mas não recomendada, uma vez que possivelmente o uso de polimorfismo possa solucionar este problema. Aliasing, tratamento de exceções e verificação estática são suportadas naturalmente. Ruby e Java possuem as mesmas características analisadas acima. Logo, elas possuem a mesma confiabilidade, sendo ideais para problemas similares em relação a segurança. Em contra partida, Hugs98 e Prolog mostram-se mais inseguras devido a falta de tratamento a exceções e verificação estática. Estas linguagens, por tanto, não podem substituir Ruby em sistemas que exijam menos riscos de falhas. 'Capacidade de Escrita' Análise Ruby é uma linguagem interpretada, de alto nível e com elementos de linguagens orientadas à objeto, imperativas e funcionais. Por isso, possui uma sintaxe complexa e redundante mas com um grande suporte à abstração e uma expressividade notável. Pode ser dito que Ruby não é uma linguagem simples. Quando comparada às linguagens de baixo nível, ela possui um número elevadíssimo de elementos sintáticos, de classes e de estruturas de fluxo o que a tornam uma linguagem pouco ortogonal e até redundante. Pode-se exemplificar a complexidade da linguagem e sua falta de ortogonalidade ao analisarmos como Ruby lida com strings de caracteres. Em Ruby, strings podem ser definidas de diversas formas diferentes, o que claramente é pouco ortogonal. Além disso, as classes String e Symbol representam conceitos muito parecidos e intercambiáveis na maioria das situações. Por outro lado, a sintaxe da linguagem possibilita uma expressividade notável, comparável às de linguagens de mais alto nível. Ruby possui métodos eficientes e sintéticos para lidar com entrada e saída e possui também, facilidade para tratar exceções. Na linguagem, a sobrescrita é facilitada por meio de namespaces e das clausuras. A tipagem em Ruby é dinâmica, o que contribui para sua expressividade, pois os tipos não precisam ser inicialmente declarados e podem ser modificados pela semântica das operações. Por fim, o tratamento que a linguagem dá às classes a torna muito expressiva. As diversas classes nativas podem tratar eficientemente vários tipos de problema como as expressões regulares que possuem suporte da classe Regex. As classes em Ruby são abertas e podem ser modificadas estática ou dinamicamente. Ruby possui ainda diversas bibliottecas disponíveis que podem ser facilmente instaladas e imediatamente utilizadas pelo programador. Ruby possui um forte suporte à orientação à objetos. Na linguagem, tudo pode ser considerado objeto e não existem tipos primitivos. Os processos são abstraídos por meio de métodos que podem ser sobrescritos devido ao polimorfismo dinâmico. Ruby emula a herança múltipla por meio dos mixins. Por fim, os seus arrays heterogêneos reforçam o forte suporte que a linguagem dá à abstração dos dados. Percebe-se que, apesar da complexidade da linguagem e de sua pouca ortogonalidade, características inerentes às linguagens interpretadas, de alto nível, a capacidade de escrita da linguagem é excelente devido à sua sintaxe eficiente e a sua grande expressividade. Comparação Comparar a capacidade de escrita de Ruby com a de Prolog ou de Hugs não é uma tarefa trivial, pois cada uma é melhor em seu domínio de aplicação, no entanto, alguns pontos podem ser levantados. O Hugs é uma linguagem que também apresenta boa expressividade. Com seus identificadores curtos, e a facilidade de se usar recursão, os programas em Hugs costumam ser bem concisos. A linguagem é mais simples e mais ortogonal do que o Ruby, porém não há suporte à abstração de dados, polimorfismo ou herança. Os mesmos comentários podem ser feitos em relação ao Prolog. Quando comparado à Java, Ruby apresenta a vantagem de ser mais conciso. Os programas em Java tendem a ser muito extensos pois suas expressões são muito longas. Ambos são igualmente complexos e pouco ortogonais. Os dois também possuem forte suporte à abstração, polimorfismo e herança. Por fim, pode-se dizer que ambas as linguagens são muito expressivas, mas devido às longas expressões de Java, Ruby possui maior expressividade e, portanto, maior capacidade de escrita. 'Legibilidade' Análise A legibilidade na linguagem Ruby sofre influência direta da forte utilização de orientação a objetos. Como seu próprio criador comenta: "Ruby is really, really object oriented programming". O código resultante é bastante limpo (poucas linhas e poucas instruções), porém a legibilidade pode ficar prejudicada pela alta ortogonalidade da linguagem, pois há diversas formas de representar a mesma ação. Comparação Podemos comparar a comfiabilidade de Ruby com a de outras linguagens de outros paradigmas: Hugs98 possui uma boa sintaxe com um conjunto de instruções poderosas. Abrange bem os tipos de dados primitivos e suas combinações enfatizado pelo uso intensivo de listas. As instruções de controle são as mesmas de outras linguagens, porém Hugs possui um mecanismo de guarda que pode disparar comandos simples até funções bastante complexas. Sua ortogonalidade é elevada, pois possibilita a utilização de seus recursos básicos para formação de senteças complexas. Isso faz dela uma linguagem que tem uma simplicidade geral mediana. Prolog possui uma sintaxe baseada em regras e fatos, analisadas por uma máquina de inferência. Como as regras e fatos são imputados pelo programador, pensamos que elas podem ser tão elaboradas quanto se quiser, levando a uma certa complexidade de entendimento dos programas. As intruções de controle estão implicitamente inseridas nas querys confontadas com as regras e os fatos da base de conhecimento, por meio do casamento de padrões e do método backtracking. Sua ortogonalidade é elevada pelo motivo exposto acima. Também consideramos a simplicidade geral elevada, pois são poucas as restrições sintáticas nativas à linguagem, cabendo ao programador sua articulação. Java possui uma boa sintaxe com um conjunto de intruções poderosas. Abrange bem os tipos de dados primitivos e suas combinações. Ela separa explicitamente os tipos de dados primitivos dos objetos, sendo estes a base para as inúmeras classes diferenctes que a linguagem possui. As instruções de controle são as mesmas de outras linguagens.Sua ortogonalidade é elevada, pois possibilita a utilização de seus recursos básicos para formação de senteças realmente complexas. A prática na programação da linguagem Java tem sido a identificação das classes e métodos correspondentes separados por pontos. Tendo em vista a grande variedade de classes e o sem número de métodos relacionados, a legibilidade fica um pouco prejudicada ficando com uma simplicidade geral baixa. Ruby possui uma boa sintaxe com um conjunto de intruções poderosas. Todos os tipos de dados são objetos e disso deriva uma facilidade de manipulação e resolução de problemas invejável. As instruções de controle são as mesmas de outras linguagens, porém apresenta os complementos lógicos das instruções if (unless) e while (until). Pensamos que os mesmos poderiam ser obtidos pela negação do argumento das instruções acima (if / while) o que justificaria o não uso do unless/until.Sua ortogonalidade é elevada, pois possibilita a utilização de seus recursos básicos para formação de senteças realmente complexas. A linguagem possibilita realizar ações complexas com uma quantidade surpreendentemente pequena de instruções o que leva a uma simplicidade 'Portabilidade' Análise Ruby é altamente portável, isto signiﬁca que um programa Ruby executa sem nenhuma mudança em qualquer plataforma. É claro que isto somente é verdade se você não estiver utilizando modulos especíﬁcos de uma plataforma, como algumas GUIs para UNIX ou WinGKR (Win32 GUI Kit for Ruby). Isto traz como vantagens um menor custo, porque apenas um programa deve ser gerenciado e uma maior distribuição do programa, além dele poder ser executado em várias plataformas. Comparação Prolog e Hugs tem uma boa portabiidade porque não são compiladas, são apenas interpretadas em um ambiente de execução. Desta forma, qualquer máquina com este ambiente pode executar aplicações destas linguagens. Mostram uma portabilidade similar a Java, que roda em uma virtual machine. Neste aspecto, Ruby se mostra similar as outras linguagens. 'Generalidade' Análise Ruby é implementável a uma faixa bastante extensa de aplicações, bem como boa parte das linguagens orientadas a objetos. Seu uso mais popular é no desenvolvimento de aplicações web como o Ruby on Rails, voltado a orientação a bancos de dados, mas Ruby pode ser usada em muitos grandes campos, desde que não exijam processamento imediato de informações. Aplicações de desktop, scripting e até mesmo computação científica podem tomar Ruby como base. 'Qualidade de Definição' Análise A documentação de Ruby é bastante extensa e compreensiva. Suas diretivas e definições estão bem especificadas, e podem ser compreendidas facilmente por todos que experimentam a linguagem. 'Evolução' Análise É complicado prever a evolução da linguagem, mesmo da aplicação desenvolvida pela linguagem, quando notamos a grande variedade de dispositivos e tecnologias que surgem frequentemente, as quais podemos implementar em nossas aplicações. Um fator muito importante diz respeito justamente à capacidade de implementações: a portabilidade. Deve ser avaliado o que determina a faixa de utilização da linguagem e encontrar boa definição na documentação sobre a que se propõe a linguagem. 'Sintaxe' 'Comentários' Os comentários em Ruby podem ser feitos de duas formas; em linha ou em código. Quando feito em linha, deve ser precedido pelo caracter '#'. # Prazer, sou um comentario! Quando os comentários são feitos em bloco, devem ser colocados entre os tokens '=begin' e '=end'. O caracter '=' deve ser o primeiro da linha. =begin Sou um comentário de duas linhas =end 'Tipos de Dados' Em ruby, tudo é objeto, incluido os literais. Por isso, as construções abaixo são válidas. -199.abs # 199 "ice is nice".length # 11 "ruby is cool.".index("u") # 1 "Nice Day Isn't It?".downcase.uniq.sort.join # " '?acdeinsty" Os tipos de dados podem ser numéricos, textuais, símbólicos ou ainda podem ser outros objetos. Os tipos numéricos são: *Integer representa números inteiros. *Float representa números de ponto flutuante. *Fixnum representa inteiros com tamanho fixo (valores até 31 bits). *Bignum números reais com precisão arbitrária. *Complex representa números complexos. *BigDecimal representa números reais com precisão arbitrária. *Rational representa números racionais na forma dividend sobre divisor. As classes Complex, BigDecimal e Rational não são nativos do Ruby, mas se encontram na biblioteca padrão. Os tipos textuais são strings e podem ser definidas com aspas simples ou aspas duplas. As strings entre aspas simples são mais simples enquanto as strings entre aspas duplas são mais flexíveis, possuem mais caracteres de escape e podem usar variáveis: 'Olá mundo!' $salutation = 'hello' “#salutation world!\n” Ainda os tipos podem ser True, False e nil. É importante salientar que não existe uma classe Boolean e que True e False são diferentes de 0 e 1, mas também são usados para representar valores lógicos. O tipo nil representa a ausência de valores e pode ser interpretado como false em uma expressão lógica. 'Arrays, Hashes e Ranges' Arrays em Ruby são coleções heterogêneas de objetos indexados por números inteiros. a = 'hi', 3.14, 1, 2, [4, 5] As seguintes operações são válidas: puts a2 # 3.14 puts a.[](2) # 3.14 puts a.reverse # [5, 2, 1, 3.14, 'hi', 1] puts a.flatten.uniq # 'hi', 3.14, 2, 4, 5 a8 # retorna nil a-8 # retorna nil a = a + 7 # 'hi', ... , [4,5, 7] a8 = 7 # 'hi', ... , [4,5, nil, nil, 7] Hashes são arrays associativos em que os índices não são numéricos mas textuais. Com isso, tem-se um par (chave, valor). Pode ser declarado conforme: hash = { :water => 'wet', :fire => 'hot' } Em seguida, pode ser usado como em: hash.each_pair do |key, value| # Or: hash.each do |key,value| puts "#{key} is #{value}" # Prints: water is wet end # fire is hot Ranges são faixas de valores que são operados como um objeto quailquer. Permitem maior flexibilidade na codificação. Veja os exemplos: r = 'a'..'z' r.each 'Hello world' Criar um programa em Ruby pode ser extremamente simples. 1. Crie um arquivo hello.rb com o comando puts 'Hello World!' 2. Executar o comando no shell $ ruby hello.rb Hello World!